﻿// E-Book Copier
// Copyright (C) 2009 Chuan-Gen Fan
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Project: http://code.google.com/p/ebookcopier/
// Contact Author:
//    website: http://chuangen.name/
// e-mail/msn: chuangen@live.cn

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Drawing.Text;

namespace EbookCopier
{
    /// <summary>
    /// 屏幕剪辑区域的边框样式。
    /// </summary>
    public enum FocusStyle
    {
        /// <summary>
        /// 正常模式
        /// </summary>
        Normal,
        /// <summary>
        /// 持续拷贝过程中。
        /// </summary>
        ContCapture,
        /// <summary>
        /// 拷贝前，拷屏区域必须为空白。
        /// </summary>
        BeforeCopy,
        /// <summary>
        /// 已经拷贝完毕，以特殊的样式提醒用户已经拷贝完成。
        /// </summary>
        AfterCopy,
    }

    /// <summary>
    /// 标识屏幕剪辑区域的窗体。可以类比照相机的取景框。
    /// </summary>
    internal class FocusRectForm : AlphaForm
    {
        StringFormat centerFormat = null;
        /// <summary>
        /// 初始化类 <see cref="FocusRectForm"/> 的新实例。
        /// </summary>
        /// <param name="screen">指定的屏幕。</param>
        public FocusRectForm(Screen screen)
            : base()
        {
            this.ClickThroughEnable = true;

            centerFormat = new StringFormat(StringFormatFlags.NoWrap);
            centerFormat.Alignment = StringAlignment.Center;
            centerFormat.LineAlignment = StringAlignment.Center;

            this.SetScreen(screen);
        }


        public int pageIndex = 0;
        /// <summary>
        /// 获取或设置 当前捕捉的页码。
        /// </summary>
        /// <value>The index of the page.</value>
        public int PageIndex
        {
            get { return pageIndex; }
            set
            {
                if (pageIndex == value)
                    return;
                pageIndex = value;

                UpdateLens();
            }
        }



        Point nextPageMouseLocation = Point.Empty;
        /// <summary>
        /// 获取或设置 “下一页”按钮的鼠标点击位置。
        /// </summary>
        /// <value>鼠标点击位置</value>
        public Point NextPageMouseLocation
        {
            get { return nextPageMouseLocation; }
            set
            {
                if (nextPageMouseLocation == value)
                    return;
                nextPageMouseLocation = value;

                UpdateLens();
            }
        }
        Point prevPageMouseLocation = Point.Empty;
        /// <summary>
        /// 获取或设置 “上一页”按钮的鼠标点击位置。
        /// </summary>
        /// <value>鼠标点击位置</value>
        public Point PrevPageMouseLocation
        {
            get { return prevPageMouseLocation; }
            set
            {
                if (prevPageMouseLocation == value)
                    return;
                prevPageMouseLocation = value;

                UpdateLens();
            }
        }


        Rectangle selectedRect = Rectangle.Empty;
        /// <summary>
        /// 获取或设置 屏幕剪辑区域。
        /// </summary>
        public Rectangle SelectedRect
        {
            get { return selectedRect; }
            set
            {
                if (selectedRect == value)
                    return;
                selectedRect = value;

                UpdateLens();
            }
        }

        FocusStyle focusStyle = FocusStyle.Normal;
        /// <summary>
        /// 获取或设置 屏幕剪辑区域边框样式。
        /// </summary>
        /// <value>样式。</value>
        public FocusStyle FocusStyle
        {
            get { return focusStyle; }
            set
            {
                if (focusStyle == value)
                    return;
                focusStyle = value;

                UpdateLens();
            }
        }
        Bitmap bmp = new Bitmap(1024, 768);
        /// <summary>
        /// 设置要显示剪辑区域边框的屏幕。
        /// </summary>
        /// <param name="screen">The screen.</param>
        public void SetScreen(Screen screen)
        {
            Rectangle bounds = screen.Bounds;
            if (bmp != null)
            {
                bmp.Dispose();
                bmp = null;
            }
            bmp = new Bitmap(bounds.Width, bounds.Height);
            this.Bounds = screen.Bounds;

            UpdateLens();
        }



        /// <summary>
        /// 更新界面。
        /// </summary>
        void UpdateLens()
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Transparent);

                //绘制鼠标点击位置
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.TextRenderingHint = TextRenderingHint.SystemDefault;
                if (prevPageMouseLocation != Point.Empty)
                {
                    g.DrawPath(Pens.Red, Common.GetFocusGraphicsPath(prevPageMouseLocation, 12, 8, 3));
                    g.DrawString("上一页", new Font("宋体", 9), Brushes.Red,
                        new Point(prevPageMouseLocation.X + 12, prevPageMouseLocation.Y - 5));
                }
                if (nextPageMouseLocation != Point.Empty)
                {
                    g.DrawPath(Pens.Red, Common.GetFocusGraphicsPath(nextPageMouseLocation, 12, 8, 3));
                    g.DrawString("下一页", new Font("宋体", 9), Brushes.Red,
                        new Point(nextPageMouseLocation.X + 12, nextPageMouseLocation.Y - 5));
                }

                g.SmoothingMode = SmoothingMode.Default;

                if (selectedRect.Width > 0 && selectedRect.Height > 0)
                {
                    OnPaintFocusRect(g, selectedRect, focusStyle);
                }
            }

            this.SetBitmap(bmp);
            this.TopMost = true;
        }

        Color color = Color.Green;
        /// <summary>
        /// 剪辑区域边框的颜色。
        /// </summary>
        public Color FocusBorderColor
        {
            get { return color; }
            set
            {
                if(color == value)
                    return;
                color = value;

                UpdateLens();
            }
        }
        /// <summary>
        /// 绘制捕捉框。
        /// </summary>
        /// <param name="g">Graphics 实例。</param>
        /// <param name="rect">要标识的区域</param>
        /// <param name="style">边框样式。</param>
        void OnPaintFocusRect(Graphics g, Rectangle rect, FocusStyle style)
        {
            //四个角的位置
            Point[] points = new Point[]{
                            new Point(rect.Left,rect.Top),
                            new Point(rect.Left,rect.Bottom),
                            new Point(rect.Right,rect.Top),
                            new Point(rect.Right,rect.Bottom),
                        };

            //半透明的宽线
            Pen penBorder = new Pen(Color.FromArgb(100, color), 4);
            //窄虚线
            Pen penFocus = new Pen(color, 1);
            penFocus.DashStyle = DashStyle.Dash;
            //g.DrawRectangle(pen, new Rectangle(rect.X - 10, rect.Y - 10, rect.Width + 20, rect.Height + 20));

            switch (style)
            {
                case FocusStyle.Normal:
                    {
                        g.SmoothingMode = SmoothingMode.Default;
                        if (rect.Width > 50 && rect.Height > 50)
                        {
                            g.DrawLine(penFocus, rect.Left + 20, rect.Top, rect.Right - 20, rect.Top);//上边线
                            g.DrawLine(penFocus, rect.Left + 20, rect.Bottom, rect.Right - 20, rect.Bottom);//下边线
                            g.DrawLine(penFocus, rect.Left, rect.Top + 20, rect.Left, rect.Bottom - 20);
                            g.DrawLine(penFocus, rect.Right, rect.Top + 20, rect.Right, rect.Bottom - 20);

                            for (int i = 0; i < points.Length; i++)
                                g.DrawPath(new Pen(color, 1), Common.GetFocusGraphicsPath(points[i], 12, 8, 3));
                        }
                        else
                        {//框太小了，只画个矩形
                            g.DrawRectangle(penFocus, rect);
                        }

                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        if (rect.Width >= 100 && rect.Height >= 100)
                        {
                            //绘制定位点
                            GraphicsPath path = Common.GetFocusGraphicsPath(
                                new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2),
                                30, 30, 10);
                            g.DrawPath(penBorder, path);
                        }

                        if (rect.Width > 250 && rect.Height > 100)
                        {//宽度 > 200，则显示字体
                            g.TextRenderingHint = TextRenderingHint.AntiAlias;
                            g.DrawString("剪辑      区域", new Font("黑体", 22.0F, FontStyle.Bold), new SolidBrush(Color.FromArgb(120, color)), rect, centerFormat);
                        }

                    }
                    break;
                case FocusStyle.ContCapture:
                    {
                        g.SmoothingMode = SmoothingMode.Default;
                        g.DrawRectangle(new Pen(Color.FromArgb(120, color), 1), rect);

                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.TextRenderingHint = TextRenderingHint.AntiAlias;
                        g.DrawString(string.Format("第 {0} 页", pageIndex), new Font("黑体", 22.0F, FontStyle.Bold), new SolidBrush(Color.FromArgb(120, color)), rect, centerFormat);
                    }
                    break;
                case FocusStyle.BeforeCopy:
                    {
                        g.SmoothingMode = SmoothingMode.Default;
                        g.DrawRectangle(penFocus, rect);
                    }
                    break;
                case FocusStyle.AfterCopy:
                    {
                        g.SmoothingMode = SmoothingMode.Default;
                        g.DrawRectangle(new Pen(Color.FromArgb(120, color), 1), rect);
                        g.FillRectangle(new SolidBrush(Color.FromArgb(60, color)), rect);

                        //g.SmoothingMode = SmoothingMode.AntiAlias;
                        //g.TextRenderingHint = TextRenderingHint.AntiAlias;
                        //g.DrawString(string.Format("第 {0} 页",pageIndex), new Font("黑体", 22.0F, FontStyle.Bold), new SolidBrush(Color.FromArgb(120, color)), rect, centerFormat);
                    }
                    break;
            }
        }
        /// <summary>
        /// 获取屏幕上指定区域的截图。
        /// </summary>
        /// <returns>截图</returns>
        public Bitmap GetSelectedScreen()
        {
            Bitmap scr = null;
            if (selectedRect.Width > 0 && selectedRect.Height > 0)
            {
                scr = new Bitmap(selectedRect.Width, selectedRect.Height);
                using (Graphics g = Graphics.FromImage(scr))
                {
                    g.CopyFromScreen(selectedRect.Location, new Point(0, 0), selectedRect.Size);
                }
            }

            return scr;
        }
    }
}
